package com.reborn.mall.api.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.reborn.mall.api.common.exception.CRUDErrorCode;
import com.reborn.mall.api.common.exception.CRUDException;
import com.reborn.mall.api.mybatis.BaseMapper;
import com.reborn.mall.api.model.entity.BaseEntity;
import com.reborn.mall.api.model.qo.PageQO;
import com.reborn.mall.api.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Objects;

/**
 * ServiceImpl 基类
 *
 * @author wu.yue
 * @since 2020/1/18
 */
@Service
public abstract class BaseServiceImpl<T extends BaseEntity> implements BaseService<T> {

    @Autowired
    private BaseMapper<T> baseMapper;

    @Override
    public T insert(T entity) {
        baseMapper.insert(entity);
        if (entity.getId() == null) {
            throw new CRUDException(CRUDErrorCode.INSERT_FAILED);
        }
        return entity;
    }

    @Override
    public T insertSelective(T entity) {
        baseMapper.insertSelective(entity);
        if (entity.getId() == null) {
            throw new CRUDException(CRUDErrorCode.INSERT_FAILED);
        }
        return entity;
    }

    @Override
    public int insertBatch(List<T> entities) {
        return baseMapper.insertList(entities);
    }

    @Override
    public T findById(Long id) {
        T found = baseMapper.selectByPrimaryKey(id);
        if (found == null) {
            throw new CRUDException(CRUDErrorCode.ENTITY_NOT_FOUND);
        }
        return found;
    }

    @Override
    public T findOne(T entity) {
        return baseMapper.selectOne(entity);
    }

    @Override
    public List<T> findAll() {
        return baseMapper.selectAll();
    }

    @Override
    public List<T> find(T entity) {
        Example example = new Example(entity.getClass());
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo(entity);
        example.setOrderByClause("sort");
        example.setOrderByClause("id desc");
        return baseMapper.selectByExample(example);
    }

    @Override
    public PageInfo<T> findPage(PageQO<T> req) {
        Objects.requireNonNull(req);
        PageHelper.startPage(req.getPageNum(), req.getPageSize());
        List<T> list = find(req.getEntity());
        return new PageInfo<>(list);
    }

    @Override
    public PageInfo<T> findPage(int pageNum, int pageSize) {
        PageQO<T> req = new PageQO<>(pageNum, pageSize, null);
        return findPage(req);
    }

    @Override
    public int updateById(T entity) {
        int affectedRows = baseMapper.updateByPrimaryKey(entity);
        if (affectedRows == 0) {
            throw new CRUDException(CRUDErrorCode.UPDATE_FAILED);
        }
        return affectedRows;
    }

    @Override
    public int updateByIdSelective(T entity) {
        int affectedRows = baseMapper.updateByPrimaryKeySelective(entity);
        if (affectedRows == 0) {
            throw new CRUDException(CRUDErrorCode.UPDATE_FAILED);
        }
        return affectedRows;
    }

    @Override
    public int deleteById(Long id) {
        int affectedRows = baseMapper.deleteByPrimaryKey(id);
        if (affectedRows == 0) {
            throw new CRUDException(CRUDErrorCode.UPDATE_FAILED);
        }
        return affectedRows;
    }

    @Override
    public int delete(T entity) {
        return baseMapper.delete(entity);
    }
}
